From 57ec74318bc134008ad886c2bdc3319127b16964 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 22 Mar 2006 10:36:02 +0100 Subject: [PATCH] SVM patch to fix problem with evtchn/lost interrupts and re-enable hvm_safe_block(). Signed-off-by: Tom Woller --- xen/arch/x86/hvm/svm/intr.c | 26 +++++++++++++++----------- xen/arch/x86/hvm/svm/svm.c | 6 ++++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/hvm/svm/intr.c b/xen/arch/x86/hvm/svm/intr.c index 430cad9372..86fc6e4b9d 100644 --- a/xen/arch/x86/hvm/svm/intr.c +++ b/xen/arch/x86/hvm/svm/intr.c @@ -58,6 +58,7 @@ static inline int svm_inject_extint(struct vcpu *v, int trap, int error_code) intr.fields.intr_masking = 1; intr.fields.vector = trap; intr.fields.prio = 0xF; + intr.fields.ign_tpr = 1; vmcb->vintr = intr; // printf( "IRQ = %d\n", trap ); return 0; @@ -160,18 +161,21 @@ asmlinkage void svm_intr_assist(void) } /* Now let's check for newer interrrupts */ else { - /* Interrput pending at the PIC? */ - hvm_pic_assist(v); - if (vpit->pending_intr_nr) { - pic_set_irq(pic, 0, 0); - pic_set_irq(pic, 0, 1); - } - - if (plat->interrupt_request) { - intr_vector = cpu_get_interrupt(v, &intr_type); - plat->interrupt_request = 0; - } + if ( v->vcpu_id == 0 ) + hvm_pic_assist(v); + + /* Before we deal with PIT interrupts, let's check + for interrupts set by the device model. + */ + if ( cpu_has_pending_irq(v) ) { + intr_vector = cpu_get_interrupt(v, &intr_type); + } + else if ( (v->vcpu_id == 0) && vpit->pending_intr_nr ) { + pic_set_irq(pic, 0, 0); + pic_set_irq(pic, 0, 1); + intr_vector = cpu_get_interrupt(v, &intr_type); + } } /* have we got an interrupt to inject? */ diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index d3fa011773..a19468a9a0 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1777,6 +1777,10 @@ static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb) __update_guest_eip(vmcb, 1); + /* check for interrupt not handled or new interrupt */ + if ( vmcb->vintr.fields.irq || cpu_has_pending_irq(v) ) + return; + if ( !v->vcpu_id ) next_pit = get_pit_scheduled(v, vpit); next_wakeup = get_apictime_scheduled(v); @@ -1784,9 +1788,7 @@ static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb) next_wakeup = next_pit; if ( next_wakeup != - 1 ) set_timer(¤t->arch.hvm_svm.hlt_timer, next_wakeup); -/* temporary workaround for 8828/8822 evtchn patches causing SVM failure. hvm_safe_block(); -*/ } -- 2.30.2